"""转码任务管理"""

import asyncio
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from pathlib import Path
from typing import Optional, Dict, Any, List


class TaskStatus(Enum):
    """任务状态枚举"""
    PENDING = "pending"
    RUNNING = "running"
    PAUSED = "paused"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


@dataclass
class TranscodeTask:
    """转码任务类"""
    
    # 基本信息
    task_id: str
    input_path: Path
    output_path: Path
    
    # 编码参数
    target_format: str = "mp4"
    quality_preset: str = "medium"
    gpu_type: str = "auto"
    
    # 状态信息
    status: TaskStatus = TaskStatus.PENDING
    progress: float = 0.0  # 0-100
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    
    # 性能指标
    current_fps: float = 0.0
    estimated_time_remaining: float = 0.0  # 秒
    
    # 错误信息
    error_message: Optional[str] = None
    
    # 元数据
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def __post_init__(self):
        """初始化后处理"""
        if not self.output_path.parent.exists():
            self.output_path.parent.mkdir(parents=True, exist_ok=True)
    
    def start(self) -> None:
        """开始任务"""
        self.status = TaskStatus.RUNNING
        self.start_time = datetime.now()
    
    def pause(self) -> None:
        """暂停任务"""
        if self.status == TaskStatus.RUNNING:
            self.status = TaskStatus.PAUSED
    
    def resume(self) -> None:
        """恢复任务"""
        if self.status == TaskStatus.PAUSED:
            self.status = TaskStatus.RUNNING
    
    def complete(self) -> None:
        """完成任务"""
        self.status = TaskStatus.COMPLETED
        self.end_time = datetime.now()
        self.progress = 100.0
    
    def fail(self, error_message: str) -> None:
        """任务失败"""
        self.status = TaskStatus.FAILED
        self.end_time = datetime.now()
        self.error_message = error_message
    
    def cancel(self) -> None:
        """取消任务"""
        self.status = TaskStatus.CANCELLED
        self.end_time = datetime.now()
    
    def update_progress(self, progress: float, fps: float = 0.0) -> None:
        """更新进度"""
        self.progress = max(0.0, min(100.0, progress))
        self.current_fps = fps
        
        # 估算剩余时间
        if self.progress > 0 and self.start_time:
            elapsed = (datetime.now() - self.start_time).total_seconds()
            total_estimated = elapsed / (self.progress / 100)
            self.estimated_time_remaining = max(0, total_estimated - elapsed)
    
    def get_duration(self) -> Optional[float]:
        """获取任务持续时间（秒）"""
        if self.start_time and self.end_time:
            return (self.end_time - self.start_time).total_seconds()
        elif self.start_time:
            return (datetime.now() - self.start_time).total_seconds()
        return None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "task_id": self.task_id,
            "input_path": str(self.input_path),
            "output_path": str(self.output_path),
            "target_format": self.target_format,
            "quality_preset": self.quality_preset,
            "gpu_type": self.gpu_type,
            "status": self.status.value,
            "progress": self.progress,
            "current_fps": self.current_fps,
            "estimated_time_remaining": self.estimated_time_remaining,
            "start_time": self.start_time.isoformat() if self.start_time else None,
            "end_time": self.end_time.isoformat() if self.end_time else None,
            "error_message": self.error_message,
            "metadata": self.metadata,
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "TranscodeTask":
        """从字典创建任务"""
        task = cls(
            task_id=data["task_id"],
            input_path=Path(data["input_path"]),
            output_path=Path(data["output_path"]),
            target_format=data["target_format"],
            quality_preset=data["quality_preset"],
            gpu_type=data["gpu_type"],
        )
        
        task.status = TaskStatus(data["status"])
        task.progress = data["progress"]
        task.current_fps = data["current_fps"]
        task.estimated_time_remaining = data["estimated_time_remaining"]
        task.error_message = data["error_message"]
        task.metadata = data["metadata"]
        
        if data["start_time"]:
            task.start_time = datetime.fromisoformat(data["start_time"])
        if data["end_time"]:
            task.end_time = datetime.fromisoformat(data["end_time"])
        
        return task